﻿'Nhiệm vụ của class
'
' - support các tác nghiệp liênq uan đến in-place-editing
'

Option Strict On
Option Explicit On 

Imports C1.Win.C1FlexGrid
Imports IP.Core.IPException
Imports IP.Core.IPUserService
Imports IP.Core.IPCommon
Imports System.Windows.forms

''' -----------------------------------------------------------------------------
''' <summary>
'''  State của các hàng trên grid trong trường hợp IED
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' 	[csung]	2/26/2005	Created
''' </history>
''' -----------------------------------------------------------------------------
Public Enum InPlaceEditRowState
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Hàng mới cần cập nhật vào DB
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	3/1/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    NewRow
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Hàng được đọc từ DB ra - Không cần làm gì với hàng thế này cả
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	3/1/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    ReadFromDB
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' hàng - đối tượng us cần update
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	3/1/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Updated
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' hàng - đối tượng cần xóa
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	3/1/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Deleted
End Enum

''' -----------------------------------------------------------------------------
''' Project	 : IPDataControl
''' Class	 : Core.IPDataControl.C1InPlaceEditControl
''' 
''' -----------------------------------------------------------------------------
''' <summary>
''' ĐỂ SUPPORT INPLACE EDITING
''' </summary>
''' <remarks>
''' Mục đích
''' quản lý những đối tượng cần cập nhật xuống CSDL gồm có 
''' <list type="bullet">
''' <item> các đối tượng cần delete</item>
''' <item> các đối tượng cần update</item>
''' <item> các đối tượng cần insert</item>
''' </list>
''' Sử dụng thế nào
''' <list type="bullet">
''' <item>
''' phải implement I_InplaceEditGridContainer. Cách implement xem ở phần container này
''' </item>
''' <item>
''' phải khởi tạo đối tượng <c> m_ied_xxx </c>
''' </item>
''' <item>
''' khi load data thì cố gắng sử dụng dataset như một member của form vì có thể phải dùng lại sau
''' này (có nhiều tiện ích support)
''' </item>
''' </list>
''' 
''' </remarks>
''' <history>
''' 	[csung]	2/26/2005	Created
''' </history>
''' -----------------------------------------------------------------------------
Public Class C1InPlaceEditControl


#Region "DATA STRUCTS"
    Private Const C_STATE_COLUMN_NAME As String = "INPLACE_ROW_STATE"
    Private Const C_ROW_STATE_NEW As String = ""
    Private Const C_ROW_STATE_READ_FROM_DB As String = "READ_FROM_DB"
    Private Const C_ROW_STATE_UPDATED As String = "UPDATED"

    Private Const c_fixed_col_index As Integer = 0
    Private Const c_error_mark_char As String = "!"
#End Region

#Region "Members"
    Private m_obj_collection_deleted As New InplaceEditedRowObjectCollection
    Private WithEvents m_fg As C1FlexGrid
    Private m_ied_grid_container As I_InplaceEditGridContainer
    Private m_b_is_editing As Boolean = False

    Private m_data_applied_2_db As New DataApplied2DB
    Private m_ied_row_object_could_not_be_applied_to_db As InplaceEditedRowObject


#End Region


#Region "PUBLIC INTERFACE"
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' trạng thái 1 hàng trên grid
    ''' </summary>
    ''' <param name="i_row_index"></param>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function get_row_state(ByVal i_row_index As Integer) As InPlaceEditRowState
        If i_row_index >= m_fg.Rows.Count Then Return InPlaceEditRowState.ReadFromDB

        Dim v_str_state_of_row As String = CType(m_fg(i_row_index, C_STATE_COLUMN_NAME), String)
        If v_str_state_of_row = C_ROW_STATE_READ_FROM_DB Then
            Return InPlaceEditRowState.ReadFromDB
        ElseIf v_str_state_of_row = C_ROW_STATE_UPDATED Then
            Return InPlaceEditRowState.Updated
        ElseIf v_str_state_of_row = C_ROW_STATE_NEW Then
            Return InPlaceEditRowState.NewRow
        End If
    End Function

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' set state của 1  hàng ( đừng dùng phía client, nếu không có nhu cầu đặc biệt)
    ''' Vì <code> mied_xxx </code> tự theo dõi cái này
    ''' </summary>
    ''' <param name="i_row_index"></param>
    ''' <param name="i_row_state"></param>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub set_row_state(ByVal i_row_index As Integer, ByVal i_row_state As InPlaceEditRowState)
        If i_row_index >= m_fg.Rows.Count Then Exit Sub
        Select Case i_row_state
            Case InPlaceEditRowState.ReadFromDB
                m_fg(i_row_index, C_STATE_COLUMN_NAME) = C_ROW_STATE_READ_FROM_DB
            Case InPlaceEditRowState.NewRow
                m_fg(i_row_index, C_STATE_COLUMN_NAME) = C_ROW_STATE_NEW
            Case InPlaceEditRowState.Updated
                m_fg(i_row_index, C_STATE_COLUMN_NAME) = C_ROW_STATE_UPDATED
        End Select
    End Sub
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Đổ dữ liệu từ dataset ra grid theo kiểu inplace-editing
    ''' </summary>
    ''' <param name="i_ds"></param>
    ''' <param name="i_fg"></param>
    ''' <param name="i_oTransfer"></param>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Shared Sub Dataset2C1Grid(ByVal i_ds As DataSet _
                                    , ByVal i_fg As C1FlexGrid _
                                    , ByVal i_oTransfer As ITransferDataRow)
        Debug.Assert(Not i_ds Is Nothing, "Chua khoi tao Dataset - tuanqt")
        Debug.Assert(Not i_fg Is Nothing, "Chua khoi tao fg - tuanqt")
        Debug.Assert(Not i_oTransfer Is Nothing, "Chua khoi tao transfer object - tuanqt")
        i_fg.Redraw = False
        Dim v_i_current_row As Integer = i_fg.Row
        ' Doan nay co the sai trong truong hop khong co mot dong nao
        ' Ask Tund if don't understand
        If (v_i_current_row < i_fg.Rows.Fixed) Then
            v_i_current_row = 0
        End If
        i_fg.Rows.Count = i_fg.Rows.Fixed

        '
        If i_ds.Tables(0).Rows.Count > 0 Then
            Dim v_iRowIndex As Integer = i_fg.Rows.Fixed
            Dim v_dr As DataRow
            For Each v_dr In i_ds.Tables(0).Rows
                i_fg.Rows.Add()
                i_fg.Rows(v_iRowIndex).UserData = v_dr
                i_oTransfer.DataRow2GridRow(v_dr, v_iRowIndex)
                i_fg(v_iRowIndex, C_STATE_COLUMN_NAME) = C_ROW_STATE_READ_FROM_DB
                v_iRowIndex += 1
            Next
        End If
        'Dat lai dong cuoi cung
        If (v_i_current_row < i_fg.Rows.Count) Then
            i_fg.Row = v_i_current_row
        Else
            ' Neu trong truong hop dong cu ma qua dong cuoi cung 
            ' thi dat o dong cuoi cung
            i_fg.Row = i_fg.Rows.Count - 1
        End If

        i_fg.Redraw = True

    End Sub
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Tạo mới đối tượng điều khiển IED
    ''' </summary>
    ''' <param name="i_fg">grid</param>
    ''' <param name="i_ied_grid_container">đối tượng chứa và xử lý grid (thường là form)</param>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub New(ByVal i_fg As C1FlexGrid, ByVal i_ied_grid_container As I_InplaceEditGridContainer)
        m_fg = i_fg
        m_ied_grid_container = i_ied_grid_container
        'ADD NEW Column ROW_STATE
        Dim v_c1_column As C1.Win.C1FlexGrid.Column = i_fg.Cols.Add()
        v_c1_column.Name = C_STATE_COLUMN_NAME
        v_c1_column.DataType = System.Type.GetType("System.String")
        v_c1_column.Caption = C_STATE_COLUMN_NAME
        v_c1_column.Visible = False

        AddHandler m_fg.AfterEdit, AddressOf m_fg_AfterEdit
    End Sub
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' reset trạng thái, thường gọi sau khi cập nhật data thành công
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub reset_data()
        m_obj_collection_deleted.Clear()
        m_b_is_editing = False
        set_all_the_rows_as_read_from_db()
    End Sub

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Xóa hàng hiện tại
    ''' </summary>
    ''' <remarks>
    ''' Thông thường gọi method này ở nút <c>Xóa</c>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub delete_current_row()
        If m_fg.Row = m_fg.Rows.Count - 1 Then Exit Sub ' dont care about last row
        'empty & new row will be removed
        If m_ied_grid_container.is_empty_row(m_fg.Row) And get_row_state(m_fg.Row) = InPlaceEditRowState.NewRow Then
            m_fg.Rows.Remove(m_fg.Row)
            Exit Sub
        End If
        'other rows
        If get_row_state(m_fg.Row) <> InPlaceEditRowState.NewRow Then
            Dim v_obj_deleted As InplaceEditedRowObject = m_ied_grid_container.get_deleted_row_object(m_fg.Row)
            v_obj_deleted.row_index = m_fg.Row
            m_obj_collection_deleted.Add(v_obj_deleted)
        End If
        m_fg.Rows.Remove(m_fg.Row)
        m_b_is_editing = True
        If m_fg.Rows.Fixed = m_fg.Rows.Count - 1 Then m_fg.Rows.Add()
    End Sub
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Trả lại các đối tượng cần delete
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function get_deleted_row_objects() As InplaceEditedRowObjectCollection
        Return m_obj_collection_deleted
    End Function

    Public Function get_updated_row_objects() As InplaceEditedRowObjectCollection
        Dim v_row_index As Integer
        Try
            Dim v_us_objects_updated As New InplaceEditedRowObjectCollection
            For v_row_index = m_fg.Rows.Fixed To index_of_last_editable_row()
                If get_row_state(v_row_index) = InPlaceEditRowState.Updated Then
                    Dim v_obj_updated As InplaceEditedRowObject = Me.m_ied_grid_container.get_updated_row_object(v_row_index)
                    v_obj_updated.row_index = v_row_index
                    v_us_objects_updated.Add(v_obj_updated)
                End If
            Next
            Return v_us_objects_updated
        Catch ex As Exception
            CSystemLog_301.ExceptionHandle(ex)
            Debug.Assert(False, "Xem lại hàng get_updated_row_object. Nó không hoạt động ở hàng " & v_row_index.ToString())
        End Try
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Cung cấp những đối tượng cần phải được insert vào CSDL
    ''' </summary>
    ''' <returns>Collection của các đối tựơng cần cập nhật</returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function get_inserted_row_objects() As InplaceEditedRowObjectCollection
        Dim v_us_object_inserted As New InplaceEditedRowObjectCollection
        Dim v_row_index As Integer
        Try
            For v_row_index = m_fg.Rows.Fixed To index_of_last_editable_row()
                If Not m_ied_grid_container.is_empty_row(v_row_index) Then
                    If get_row_state(v_row_index) = InPlaceEditRowState.NewRow Then
                        Dim v_obj_inserted As InplaceEditedRowObject = Me.m_ied_grid_container.get_new_row_object(v_row_index)
                        v_obj_inserted.row_index = v_row_index
                        v_us_object_inserted.Add(v_obj_inserted)
                    End If
                End If
            Next
            Return v_us_object_inserted
        Catch ex As Exception
            CSystemLog_301.ExceptionHandle(ex)
            Debug.Assert(False, "Xem lại hàng get_inserted_row_object. Nó không hoạt động ở hàng " & v_row_index.ToString())
        End Try
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Sau khi gọi apply_for_changes thì gọi để kiểm lỗi
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function get_error_raising_row_object() As InplaceEditedRowObject
        Debug.Assert(Not (m_ied_row_object_could_not_be_applied_to_db Is Nothing), "Đã cập nhật đâu mà gọi")
        Return m_ied_row_object_could_not_be_applied_to_db
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Apply tất cả các thay đổi về phía DB
    ''' </summary>
    '''<remarks>
    ''' <list type="bullet">
    ''' <item> remove các hàng mới mà empty </item>
    ''' <item> xóa các hàng cần xóa</item>
    ''' <item> update các hàng cần update</item>
    ''' <item> thêm mới các hàng cần thêm mới</item>
    ''' </list>
    '''
    ''' <list type="bullet">
    ''' <item>
    ''' Chú ý là chỉ cập nhật xuống CSDL. Nếu bạn muốn đồng bộ với dataset và chỉnh ID cũng
    ''' như datarow của từng hàng thì bạn hãy gọi <c> reconcile_grid_data_with_dataset_and_database</c>
    ''' </item>
    ''' <item>
    ''' Đây chỉ là một tiện ích nếu bạn muốn tự mình delete, insert,  update thì bạn hãy gọi
    ''' các hàm <c>get_deleted_row_objects</c>,<c> get_inserted_row_objects</c>, <c> get_updated_row_objects</c>
    ''' để lấy những dữ liệu cần xử lý.
    ''' </item>
    ''' </list>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub apply_all_changes()
        Dim v_us As New US_Object
        'đây chỉ để ghi lại lỗi đã xảy ra
        m_ied_row_object_could_not_be_applied_to_db = Nothing
        Dim v_ied_row_object_in_work As InplaceEditedRowObject
        Try
            'clear new row in grid that totally empty
            remove_newly_created_empty_row()

            v_us.open_connection()

            'for each deleted row
            Dim v_deleted_row_object As InplaceEditedRowObject
            For Each v_deleted_row_object In m_obj_collection_deleted
                v_ied_row_object_in_work = v_deleted_row_object ' chỉ để dữ lại xem đói tượnglàm việc cúoi cucng là gi
                Dim v_dc_id As Decimal = CType(v_deleted_row_object.original_data_row("ID"), Decimal)
                v_deleted_row_object.edited_us_object.use_connection(v_us.get_connection)
                v_deleted_row_object.edited_us_object.DeleteByID(v_dc_id)
            Next
            '
            ' for each updated row
            '

            Dim v_objs_updated As InplaceEditedRowObjectCollection = Me.get_updated_row_objects
            Dim v_updated_row_object As InplaceEditedRowObject
            For Each v_updated_row_object In v_objs_updated
                v_ied_row_object_in_work = v_updated_row_object ' chỉ để dữ lại xem đói tượnglàm việc cúoi cucng là gfi
                v_updated_row_object.edited_us_object.use_connection(v_us.get_connection)
                Debug.Write(v_updated_row_object.edited_us_object.ToString())
                v_updated_row_object.edited_us_object.Update()
            Next

            '
            ' for each new row
            '
            Dim v_objs_inserted As InplaceEditedRowObjectCollection = Me.get_inserted_row_objects
            Dim v_inserted_row_object As InplaceEditedRowObject
            For Each v_inserted_row_object In v_objs_inserted
                v_ied_row_object_in_work = v_inserted_row_object ' chỉ để dữ lại xem đói tượnglàm việc cúoi cucng là gfi
                v_inserted_row_object.edited_us_object.use_connection(v_us.get_connection)
                Debug.Write(v_inserted_row_object.edited_us_object.ToString())
                v_inserted_row_object.edited_us_object.Insert()
            Next
            v_us.commit_close_connection()
            ''' mark data succeessfully updated to DB
            mark_data_submitted_2_db(m_obj_collection_deleted, _
                                   v_objs_updated, _
                                   v_objs_inserted)
            
        Catch v_e As Exception
            m_ied_row_object_could_not_be_applied_to_db = v_ied_row_object_in_work
            If v_us.is_having_connection Then
                v_us.rollback_close_connection()
            End If
            Throw v_e  ' không xử lý dữ liệu ở đây
        End Try
    End Sub



    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Xóa khỏi GRID những hàng mới và empty ( empty theo cách hiểu của ied grid container
    ''' </summary>
    ''' <remarks>
    ''' Những hàng này không cần quan tâm đến. Trong số những hàng empty có thể có
    ''' <list type="bullet">
    ''' <item> những hàng mới (bị xóa bởi method này)</item>
    ''' <item> những hàng bị update thành empty (những hàng này chắc chắn không thể
    ''' cập nhật xuống được</item> 
    ''' </list>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub remove_newly_created_empty_row()
        Dim v_index_of_grid_row As Integer = m_fg.Rows.Fixed
        While v_index_of_grid_row <= index_of_last_editable_row()
            If m_ied_grid_container.is_empty_row(v_index_of_grid_row) _
               And Me.get_row_state(v_index_of_grid_row) = InPlaceEditRowState.NewRow Then
                m_fg.Rows.Remove(v_index_of_grid_row)
            End If
            v_index_of_grid_row += 1
        End While
    End Sub
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Có đang có dữ liệu bị edit không
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function is_editing() As Boolean
        Return m_b_is_editing
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Kế thúc edit trên cell hiện tại. 
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' Thường gọi trước khi cập nhật dữ liệu xuống DB
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function finishEditingCurrentCell() As Boolean
        Return m_fg.FinishEditing()
    End Function

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Đổ dữ liệu từ dataset cũ vào grid, mọi thứ như mới load
    ''' </summary>
    ''' <param name="i_ds_original_data">dataset cũ</param>
    ''' <param name="i_oTransfer">đối tượng đổ 1 datarow ra 1 gridrow</param>
    ''' <remarks>
    ''' Thường được gọi bởi nút undo
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub undo_changes(ByVal i_ds_original_data As DataSet, ByVal i_oTransfer As ITransferDataRow)
        C1InPlaceEditControl.Dataset2C1Grid(i_ds_original_data, m_fg, i_oTransfer)
        Me.reset_data()
    End Sub
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Đồng bộ dữ liệu GRID - DATASET - DATABASE
    ''' </summary>
    ''' <param name="i_ds_original_data">DATASET cũ</param>
    ''' <param name="i_oTransfer">đối tượng đổi datarow thành gridrow </param>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub reconcile_grid_data_with_dataset_and_database(ByVal i_ds_original_data As DataSet, _
                                                             ByVal i_oTransfer As ITransferDataRow)
        ' Đồng bộ dữ liệu với csdl, original dataset 
        ' Có thể gọi được sau khi apply_all_changes
        '
        Dim v_obj_deleted As InplaceEditedRowObject
        ' delete the row deleted in DB
        For Each v_obj_deleted In m_obj_collection_deleted
            v_obj_deleted.original_data_row.Delete()
        Next
        'inserted rows
        If Not (m_data_applied_2_db.m_inserted_objects Is Nothing) Then
            Dim v_obj_inserted As InplaceEditedRowObject
            For Each v_obj_inserted In Me.m_data_applied_2_db.m_inserted_objects
                Dim v_new_data_row As DataRow = i_ds_original_data.Tables(0).NewRow()
                v_obj_inserted.edited_us_object.Me2DataRow(v_new_data_row)
                i_ds_original_data.Tables(0).Rows.Add(v_new_data_row)
                i_oTransfer.DataRow2GridRow(v_new_data_row, v_obj_inserted.row_index)
                m_fg.Rows(v_obj_inserted.row_index).UserData = v_new_data_row
            Next
        End If
        'updated rows
        If Not (m_data_applied_2_db.m_updated_objects Is Nothing) Then
            Dim v_obj_updated As InplaceEditedRowObject
            For Each v_obj_updated In Me.m_data_applied_2_db.m_updated_objects
                v_obj_updated.edited_us_object.Me2DataRow(v_obj_updated.original_data_row)
            Next
            'Accept Changes
            i_ds_original_data.Tables(0).AcceptChanges()
        End If
        'reset all data
        Me.reset_data()
    End Sub
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[csung]	2/26/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub mark_grid_row_as_error(ByVal i_grid_row_index As Integer)
        set_row_as_error_prone(i_grid_row_index, True)
    End Sub

    ''' De biet xem data da apply xuong DB la gi
    ''' Khong xuat hien error trong khi apply thay doi vao dB
    '''
    Public Sub mark_data_submitted_2_db( _
                    ByVal i_deleted_objects As InplaceEditedRowObjectCollection, _
                    ByVal i_updated_objs As InplaceEditedRowObjectCollection, _
                    ByVal i_inserted_objs As InplaceEditedRowObjectCollection)
        m_data_applied_2_db.m_deleted_objects = i_deleted_objects
        m_data_applied_2_db.m_inserted_objects = i_inserted_objs
        m_data_applied_2_db.m_updated_objects = i_updated_objs
        'clear error causing object in work
        m_ied_row_object_could_not_be_applied_to_db = Nothing
    End Sub
#End Region

#Region "Event Handlers"
    Public Sub m_fg_AfterEdit(ByVal sender As Object, ByVal e As C1.Win.C1FlexGrid.RowColEventArgs)
        Select Case get_row_state(e.Row)
            Case InPlaceEditRowState.ReadFromDB
                set_row_state(e.Row, InPlaceEditRowState.Updated)
                m_b_is_editing = True
            Case InPlaceEditRowState.NewRow
                set_row_state(e.Row, InPlaceEditRowState.NewRow)
                m_b_is_editing = True
        End Select
    End Sub
#End Region

#Region "Private"
    Private Function index_of_last_editable_row() As Integer
        Dim v_i_last_row_editable As Integer
        If m_fg.AllowAddNew Then
            Return m_fg.Rows.Count - 1
        Else
            Return m_fg.Rows.Count - 1
        End If
        Return v_i_last_row_editable
    End Function

    Private Sub set_all_the_rows_as_read_from_db()
        Dim v_index As Integer
        For v_index = m_fg.Rows.Fixed To index_of_last_editable_row()
            set_row_state(v_index, InPlaceEditRowState.ReadFromDB)
            set_row_as_error_prone(v_index, False)
        Next
    End Sub

    Private Sub set_row_as_error_prone(ByVal i_i_index As Integer, ByVal i_b_set_as_error As Boolean)
        If i_b_set_as_error Then
            'Dim v_error_cell_style As C1.Win.C1FlexGrid.CellStyle
            'v_error_cell_style.Font = New System.Drawing.Font("Arial", 8, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
            'v_error_cell_style.ForeColor = System.Drawing.Color.Red
            m_fg(i_i_index, c_fixed_col_index) = c_error_mark_char
        Else
            m_fg(i_i_index, c_fixed_col_index) = ""
        End If
    End Sub

    Private Class DataApplied2DB
        '' data da apply to Db la gi
        ''
        Public m_deleted_objects As InplaceEditedRowObjectCollection
        Public m_inserted_objects As InplaceEditedRowObjectCollection
        Public m_updated_objects As InplaceEditedRowObjectCollection
    End Class

#End Region




End Class





